#include <iostream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define COMMAND_SIZE 1024
#define FORMAT "%s@%s %s]# " 

#define MAX_ARGC 128
char* argv[MAX_ARGC];
int argc = 0;


const char* UserName()
{
    const char* name = getenv("USER");
    return name == NULL ? "None" : name;
}

const char* HostName()
{
    const char* hostname = getenv("HOSTNAME");
    return hostname == NULL ? "None" : hostname;
}

const char* GetPwd()
{
    const char* pwd = getenv("PWD");
    return pwd == NULL ? "None" : pwd;
}

std::string DirName(const char* pwd)
{
#define SLASH "/"
    std::string dir = pwd;
    if(dir == SLASH) return SLASH;
    auto pos = dir.rfind(SLASH);
    if(pos == std::string::npos) return "BUG?";
    return dir.substr(pos+1);
}

void MakeCommandLine(char cmd_prompt[],int size)
{
   snprintf(cmd_prompt,size,FORMAT,UserName(),HostName(),DirName(GetPwd()).c_str());
}

void PrintCommandLine()
{
    char prompt[COMMAND_SIZE];
    MakeCommandLine(prompt,sizeof(prompt));
    printf("%s",prompt);
    fflush(stdout);
}

bool GetCommandLine(char* out,int size)
{  
    
    char* c = fgets(out,size,stdin);
    if( c == NULL) return false;
    out[strlen(out)-1] = 0; //清理\n
    if(strlen(out)==0) return false;
    //printf("echo %s\n",out);
    return true;
}

bool CommandParse(char* commandline)
{
#define SEP " "
   argc = 0;
   argv[argc++] = strtok(commandline,SEP);
   while((bool)(argv[argc++] = strtok(nullptr,SEP)));
   argc--;
   return true;
}

void PrintArgv()
{
    for(int i = 0;argv[i];i++)
    {
        printf("argv[%d]-> %s\n",i,argv[i]);
    }
    
    printf("argc-> %d\n",argc);
}
int Execute()
{
    pid_t id = fork();
        
   if(id == 0)
   {
       execvp(argv[0],argv);
       exit(1);
   }

   //父进程
   pid_t rid = waitpid(id,nullptr,0);
   (void)rid;
   
   return 1;
}
int main()
{
        while(true)
        {
            //1.打印命令行信息
            PrintCommandLine();
            //2.获取命令行参数
            char commandline[COMMAND_SIZE];
            
            if(!GetCommandLine(commandline,sizeof(commandline)))
                continue;
            //3.分析命令行 "ls -a -l" -> "ls" "-a" "-l"
            CommandParse(commandline);
            //PrintArgv();

            //4.执行命令
            Execute();
        
        }
    return 0;
}


